
use crate::{string::serdejson::JsonVExentd, sync::map_hash::SyncHashMap};
pub struct SerdeConfig {
    /// 程序名称
    pub app_name: String,
    /// 程序版本
    pub version: String,
    /// 编译时间
    pub compile_time: String,
    /// 配置详情
    pub map_pairs: SyncHashMap<String, serde_json::Value>,
}

impl SerdeConfig {
    pub fn new(app_name: String, version: String, compile_time: String) -> Self {
        Self {
            app_name,
            version,
            compile_time,
            map_pairs: SyncHashMap::new(),
        }
    }
    pub fn info(&self) -> String {
        let mut buf = format!("【{}】配置信息:\n", self.app_name);
        buf.push_str(&format!("\t编译时间: {}\n", self.compile_time));
        buf.push_str(&format!("\t版 本 号: {}\n", self.version));
        buf.push_str(&format!("\t配置详情: 共 {} 项:(开始)\n", self.map_pairs.len()));
        for (index, (k, v)) in self.map_pairs.iter().enumerate() {
            buf.push_str(&format!("\t\t{}. {k}: {v:?}\n", index + 1 ));
        }
        buf.push_str(&format!("\t配置详情: 共 {} 项:(结束)\n", self.map_pairs.len()));

        buf
    }
}

impl SerdeConfig {
    pub fn append(&self, map_config: serde_json::Map<String, serde_json::Value>) {
        let len = map_config.len();
        let mut len_flattern = 0;
        for (k, v) in map_config {
            if let serde_json::Value::Object(v1) = v {
                for (k2, v2) in v1 {
                    warn!("{k}:{k2}={v2}");
                    self.map_pairs.insert(format!("{k}:{k2}"), v2);
                    len_flattern += 1;
                }
            } else {
                self.map_pairs.insert(k, v);
                len_flattern += 1;
            }
        }
        warn!("{} 批量导入 {len_flattern} 条配置信息 / {len}(类)", self.app_name);
    }

    pub fn get_string(&self, key: &str, default: String, description: &str) -> String {
        let (msg, value) = match self.map_pairs.get(key) {
            Some(j_v) => {
                match j_v.as_string2() {
                    Some(v) => (format!("【{description}】字符串型配置: {key} = {v}"), v),
                    None => (format!("【{description}】字符串型配置: 取默认值 {default}, 用户指定 {key}={j_v} 无效解析."), default),
                }
            },
            None => (format!("【{description}】字符串型配置: 取默认值 {default}, 用户没有指定 {key}."), default),
        };
        warn!("{msg}");
        value
    }

    pub fn get_bool(&self, key: &str, description: &str) -> bool {
        let default = false;
        let (msg, value) = match self.map_pairs.get(key) {
            Some(j_v) => {
                match j_v.as_bool() {
                    Some(v) => (format!("【{description}】布尔型配置: {key} = {v}"), v),
                    None => (format!("【{description}】布尔型配置: 取默认值 {default}, 用户指定 {key}={j_v} 无效解析."), default),
                }
            },
            None => (format!("【{description}】布尔串型配置: 取默认值 {default}, 用户没有指定 {key}."), default),
        };
        warn!("{msg}");
        value
    }

    pub fn get_i64(&self, key: &str, default: i64, description: &str) -> i64 {
        let (msg, value) = match self.map_pairs.get(key) {
            Some(j_v) => {
                match j_v.as_i64() {
                    Some(v) => (format!("【{description}】整数型配置: {key} = {v}"), v),
                    None => (format!("【{description}】整数型配置: 取默认值 {default}, 用户指定 {key}={j_v} 无效解析."), default),
                }
            },
            None => (format!("【{description}】整数型配置: 取默认值 {default}, 用户没有指定 {key}."), default),
        };
        warn!("{msg}");
        value
    }

    pub fn get_f64(&self, key: &str, default: f64, description: &str) -> f64 {
        let (msg, value) = match self.map_pairs.get(key) {
            Some(j_v) => {
                match j_v.as_f64() {
                    Some(v) => (format!("【{description}】浮点数型配置: {key} = {v}"), v),
                    None => (format!("【{description}】浮点数型配置: 取默认值 {default}, 用户指定 {key}={j_v} 无效解析."), default),
                }
            },
            None => (format!("【{description}】浮点数型配置: 取默认值 {default}, 用户没有指定 {key}."), default),
        };
        warn!("{msg}");
        value
    }

}
